package com.tanhua.server.serivce;

import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.commons.template.OssTemplate;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.mongo.FollowUser;
import com.tanhua.domain.mongo.Video;
import com.tanhua.domain.vo.CommentVo;
import com.tanhua.domain.vo.ErrorResult;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.VideoVo;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.mongo.CommentApi;
import com.tanhua.dubbo.api.mongo.VideoApi;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.commons.collections.CollectionUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class VideoService {

    // 注入dubbo服务接口的代理对象
    @Reference
    private VideoApi videoApi;
    @Reference
    private UserInfoApi userInfoApi;
    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private FastFileStorageClient storageClient;
    @Autowired
    private FdfsWebServer fdfsWebServer;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private VideoMqService videoMqService;

    @Reference
    private CommentApi commentApi;

    /**
     * 接口名称：小视频列表
     */
    //@Cacheable(value = "videoList",key = "#page + '_' + #pagesize")
    public PageResult queryVideoList(Integer page, Integer pagesize) {
        System.out.println("---------------->小视频列表查询数据库！");
        //1、调用api分页查询小视频
        //【先从redis中获取推荐视频，如果没有获取到，查询默认的数据】
        PageResult pageResult = findRecommend(page, pagesize);
        if (pageResult == null) {
            pageResult = videoApi.findByPage(page, pagesize);
        }

        List<Video> videoList = (List<Video>) pageResult.getItems();

        //2、创建返回的vo集合对象
        List<VideoVo> voList = new ArrayList<>();

        //3. 封装数据
        if (videoList != null) {
            for (Video video : videoList) {
                //3.1 创建vo对象，封装前端返回的数据
                VideoVo vo = new VideoVo();
                BeanUtils.copyProperties(video, vo);
                //3.2 根据用户id查询用户并封装
                UserInfo userInfo = userInfoApi.findById(video.getUserId());
                if (userInfo != null) {
                    BeanUtils.copyProperties(userInfo, vo);
                }
                //3.3 设置小视频封面
                vo.setCover(video.getPicUrl());
                //3.4 设置id、签名
                vo.setId(video.getId().toString());
                vo.setSignature(video.getText());
                String keyLike = "Video_Like_" + UserHolder.getUserId() + "_" + video.getId().toString();
                if (redisTemplate.hasKey(keyLike)) {
                    vo.setHasLiked(0);
                } else {
                    vo.setHasLiked(1);
                }
                String key = "followUser_" + UserHolder.getUserId() + "_" + vo.getUserId();
                if (redisTemplate.hasKey(key)) {
                    vo.setHasFocus(1);// 视频已关注
                } else {
                    vo.setHasFocus(0);
                }
                //3.5 vo添加到集合
                voList.add(vo);
            }
        }

        //4. 设置到PageResult中
        pageResult.setItems(voList);

        //5. 响应
        return pageResult;
    }

    private PageResult findRecommend(Integer page, Integer pagesize) {
        //1. redis中的key
        String key = "QUANZI_VIDEO_RECOMMEND_" + UserHolder.getUserId();
        //2. 根据key获取推荐的视频vid
        String value = redisTemplate.opsForValue().get(key);
        //3. 判断
        if (StringUtils.isEmpty(value)) {
            return null;
        }
        //4. 分页查询推荐数据
        String[] vids = value.split(","); //1,2,3,4,5,6,7,8,9
        int counts = vids.length;
        int startIndex = (page - 1) * pagesize; //计算本页的起始条数

        if (startIndex < vids.length) { //起始条数小于数据总数
            int endIndex = startIndex + pagesize - 1;
            if (endIndex >= vids.length) {
                endIndex = vids.length - 1;
            }
            List<Long> pidList = new ArrayList<>();   //本页查询的所有动态的pid列表
            for (int i = startIndex; i <= endIndex; i++) {
                pidList.add(Long.valueOf(vids[i]));
            }
            //本次分页的数据列表
            List<Video> list = videoApi.findByVids(pidList);
            return new PageResult(page, pagesize, counts, list);
        }
        return null;
    }

    /**
     * 接口名称：视频上传
     */
    @CacheEvict(value = "videoList", allEntries = true)
    public ResponseEntity<Object> uploadVideos(
            MultipartFile videoThumbnail, MultipartFile videoFile, String text) throws IOException {
        //1. 视频封面（videoThumbnail） 上传到阿里云
        String picUrl =
                ossTemplate.upload(videoThumbnail.getOriginalFilename(),
                        videoThumbnail.getInputStream());

        //2. 视频上传到fastdfs
        String videoFileName = videoFile.getOriginalFilename();
        String ext = videoFileName.substring(videoFileName.lastIndexOf(".") + 1);
        StorePath storePath = storageClient.uploadFile(videoFile.getInputStream(), videoFile.getSize(), ext, null);
        String videoUrl = fdfsWebServer.getWebServerUrl() + storePath.getFullPath();

        //3. 保存video
        Video video = new Video();
        video.setCreated(System.currentTimeMillis());
        video.setUserId(UserHolder.getUserId());
        if (StringUtils.isEmpty(text)) {
            video.setText("左手右手一个慢动作~");
        } else {
            video.setText(text);
        }
        video.setPicUrl(picUrl);
        video.setVideoUrl(videoUrl);

        //【设置id】
        video.setId(ObjectId.get());
        videoApi.save(video);

        // 【发送mq消息，用于计算操作评分】
        videoMqService.videoMsg(video.getId().toString());

        return ResponseEntity.ok(null);
    }

    /**
     * 接口名称：视频用户关注
     *
     * @param followUserId
     * @return
     */
    @CacheEvict(value = "videoList", allEntries = true)
    public ResponseEntity<Object> followUser(Long followUserId) {
        //1. 保存关注用户数据到follow_user表中
        FollowUser followUser = new FollowUser();
        followUser.setCreated(System.currentTimeMillis());
        followUser.setUserId(UserHolder.getUserId());
        followUser.setFollowUserId(followUserId);
        videoApi.followUser(followUser);

        //2. 记录关注的标记（前端点亮图表）
        String key = "followUser_" + UserHolder.getUserId() + "_" + followUser.getFollowUserId();
        redisTemplate.opsForValue().set(key, "1");
        return ResponseEntity.ok(null);
    }

    /**
     * 接口名称：视频用户关注-取消
     */
    @CacheEvict(value = "videoList", allEntries = true)
    public ResponseEntity<Object> unfollowUser(Long followUserId) {
        //1. 删除mongo中的follow_user表中的关注数据
        videoApi.unfollowUser(UserHolder.getUserId(), followUserId);

        //2. 删除redis中的关注标记
        String key = "followUser_" + UserHolder.getUserId() + "_" + followUserId;
        redisTemplate.delete(key);
        return ResponseEntity.ok(null);
    }

    /**
     * 点赞取消
     *
     * @param
     * @return
     */
    @CacheEvict(value = "videoList", allEntries = true)
    public ResponseEntity<Object> videosLike(String videoId) {

        Integer count = videoApi.videosLike(new ObjectId(videoId));
        String key = "Video_Like_" + UserHolder.getUserId() + "_" + videoId;
        redisTemplate.delete(key);

        return ResponseEntity.ok(count);
    }

    /**
     * 视频点赞
     *
     * @param
     * @return
     */
    @CacheEvict(value = "videoList", allEntries = true)
    public ResponseEntity<Object> disvideosLike(String videoId) {

        Integer count = videoApi.disvideosLike(videoId);
        // 保存哪一个用户对哪个动态进行点赞的记录
        String key = "Video_Like_" + UserHolder.getUserId() + "_" + videoId;

        redisTemplate.opsForValue().set(key, "1");


        return ResponseEntity.ok(count);
    }

    /**
     * 评论列表
     *
     * @param
     * @param page
     * @param pagesize
     * @return
     */

    public ResponseEntity<Object> queryVideoCommentList(String videoId, Integer page, Integer pagesize) {
        //1. 调用服务，查询评论列表
        PageResult pageResult = commentApi.queryVideoCommentList(videoId, page, pagesize);
        //2. 获取查询数据
        List<Comment> commentList = (List<Comment>) pageResult.getItems();
        //3. 创建返回的vo集合数据
        List<CommentVo> voList = new ArrayList<>();
        //4. 封装voList
        if (CollectionUtils.isNotEmpty(commentList)) {
            voList = commentList.stream().map(comment -> {
                CommentVo vo = new CommentVo();
                UserInfo userInfo = userInfoApi.findById(comment.getUserId());
                if (userInfo != null) {
                    BeanUtils.copyProperties(userInfo, vo);
                }
                vo.setId(comment.getId().toString());
                vo.setContent(comment.getContent());
                vo.setCreateDate(new DateTime(comment.getCreated()).toString("yyyy年MM月dd HH:mm"));
                String key = "Comment_Like_" + UserHolder.getUserId() + "_" + comment.getId();
                if (redisTemplate.hasKey(key)) {
                    vo.setLikeCount(1);
                } else {
                    vo.setLikeCount(0);
                }
                vo.setHasLiked(0);
                return vo;
            }).collect(Collectors.toList());
        }
        pageResult.setItems(voList);
        return ResponseEntity.ok(pageResult);
    }

    /**
     * 视屏评论点赞
     */
    @CacheEvict(value = "videoList", allEntries = true)
    public ResponseEntity<Object> videoCommentLike(String commentId) {

        Integer count = videoApi.saveVideoLike(new ObjectId(commentId));
        // 保存哪一个用户对哪个动态进行点赞的记录
        String key = "Comment_Like_" + UserHolder.getUserId() + "_" + commentId;

        redisTemplate.opsForValue().set(key, "1");

        return ResponseEntity.ok(count);

    }

    /**
     *  接口名称：视频评论发布
     * @param videoId
     * @param comment
     * @return
     */
    @CacheEvict(value = "videoList", allEntries = true)
    public ResponseEntity<Object> savevideoComment(String videoId, String comment) {
        Comment commrnt1 = new Comment();
        commrnt1.setCommentType(2);
        commrnt1.setPubType(2);
        commrnt1.setPublishId(new ObjectId(videoId));
        commrnt1.setContent(comment);
        commrnt1.setUserId(UserHolder.getUserId());
        commrnt1.setCreated(System.currentTimeMillis());
        UserInfo userInfo = userInfoApi.findById(UserHolder.getUserId());
        //冻结发言
        if ("2".equals(userInfo.getUserStatus())) {

            String status = redisTemplate.opsForValue().get("FREEZE_TYPE"+userInfo.getId());

            if ("2".equals(status)) {

                return ResponseEntity.status(500).body(ErrorResult.freezeCommentError());
            }
        }

        commentApi.savevideoComment(commrnt1);

        return ResponseEntity.ok(null);
    }
}
